package cn.bonoon.kernel.support.searcher;

import java.util.ArrayList;
import java.util.List;

import cn.bonoon.kernel.bytecode.EntityReader;
import cn.bonoon.kernel.events.ReadEvent;
import cn.bonoon.kernel.support.ProxyEntityManager;
import cn.bonoon.kernel.support.models.AbstractAjaxNode;
import cn.bonoon.kernel.support.models.AbstractNode;

/**
 * 自动转值查询对象
 * @author jackson
 *
 */
public class ExtendFinder extends StandardFinder{
	
	protected final EntityReader reader;
	protected final ReadEvent readEvent;
	
	public ExtendFinder(EntityReader reader, ReadEvent readEvent, ProxyEntityManager manager) {
		super(manager);
		this.reader = reader;
		this.readEvent = readEvent;
	}
	
	@Override
	protected String selectField() {
		return reader.properties();
	}
	
	@Override
	protected List<Object> __handler(List<Object> rls) throws Exception{
		List<Object> items = new ArrayList<Object>();
		if(handler == null){
			for(Object rl : rls){
				items.add(read(rl));
			}
		}else{
			for(Object rl : rls){
				Object ob = read(rl);
				Object it = handler.doHandler(rl, ob);
				if(null != it){
					items.add(it);
				}
			}
		}
		return items;
	}
	
	protected Object read(Object obj) throws Exception{
		return reader.read(readEvent, obj);
	}
	
	@Override
	protected <T> List<T> __node(int i, Long rid) throws Exception{
		parameters[i] = rid;
		
		List<T> items = new ArrayList<T>();
		for(Object rl : __query()){
			@SuppressWarnings("unchecked")
			T node = (T)read(rl);
			__parseNode(i, items, node);
		}
		return items;
	}
	
	private <T> void __parseNode(int i, List<T> items, T node) throws Exception{
		items.add(node);
		if(node instanceof AbstractNode){
			AbstractNode an = (AbstractNode)node;
			List<AbstractNode> ins = __node(i, an.getId());
			an.setChildren(ins);
		}else if(node instanceof AbstractAjaxNode){
			AbstractAjaxNode aan = (AbstractAjaxNode)node;
			int size = aan.getSize();
			aan.setState(size == 0 ? AbstractAjaxNode.OPEN : AbstractAjaxNode.CLOSED);
		}
}
	@Override
	protected List<?> __root() throws Exception{
		List<Object> nodes = __query(" and x.parent is null ");
		int i = __childrenExpression();
		
		List<Object> items = new ArrayList<Object>();
		for(Object rl : nodes){
			Object node = read(rl);
			__parseNode(i, items, node);
//			if(node instanceof AbstractNode){
//				AbstractNode an = (AbstractNode)node;
//				List<AbstractNode> ins = __node(i, an.getId());
//				an.setChildren(ins);
//			}else if(node instanceof AbstractAjaxNode){
//				AbstractAjaxNode aan = (AbstractAjaxNode)node;
//				int size = aan.getSize();
//				aan.setState(size == 0 ? AbstractAjaxNode.OPEN : AbstractAjaxNode.CLOSED);
//			}
		}
		return items;
	}
}
